import re

function= ["lcase","ucase","print"]
operators = ["plus","minus","times","divby"]


def convert_to_operator(opt):
    if opt == "plus":
        return "+"
    elif opt == "minus":
        return "-"
    elif opt == "times":
        return "*"
    elif opt == "divby":
        return "/"

def lex(line):
    part = []
    a = []

    forward_variable = -1
    forward_number = -1
    forward_operate = -1
    forward_string = -1

    for i in range(0, len(line)):
        part.append(line[i])

    for i in range(0, len(part)):  ## returns a set of tuples . each tuple has two values : type of data and the data.
        ## for ex : [("variable","x"), ("number","5")]



        if re.match("[_a-zA-Z]", part[i]):
            variable = analyze_data(i, line, "variable")  # extracting the variable from the string

            if variable not in function and  variable not in operators:
                if i > forward_variable:
                    a.append(("variable", variable))
                    forward_variable = i + len(variable) - 1
                    forward_number = i + len(variable) - 1
            if variable in function:
                a.append(("function", variable))
                forward_variable = i + len(variable) - 1
            if variable in operators:
                new_opt = convert_to_operator(variable)
                a.append(("operator", new_opt))
                forward_variable = i + len(variable) - 1


        if re.match("[.0-9]", part[i]):
            number = analyze_data(i, line, "number")
            if i > forward_number:
                a.append(("number", number))
                forward_number = i + len(number) - 1


        if part[i] == " ":
            pass

        if part[i] == '"':
            string = '"' + analyze_data(i + 1, line, "string") + '"'
            if i > forward_string:
                a.append(("string", string))
                forward_string = i + len(string) - 1
                forward_variable = i + len(string) - 1
                forward_number = i + len(string) - 1


    #print(a)
    return a


## THIS FUNCTION EXTRACTS A VARIABLE OR A NUMBER FROM A STRING


def analyze_data(index, string, type):
    variable = ""
    if type == "variable":
        for i in range(index, len(string)):
            if re.match("[_a-zA-Z]", string[i]) or re.match("[.0-9]", string[i]):
                variable += string[i]
            else:
                break

    if type == "number":
        for i in range(index, len(string)):
            if re.match("[.0-9]", string[i]):
                variable += string[i]
            else:
                break

    if type == "operator":
        for i in range(index, len(string)):
            if string[i] in operators:
                variable += string[i]
            else:
                break

    if type == "string":
        for i in range(index, len(string)):
            if string[i] != '"':
                variable += string[i]
            else:
                break

    return variable

#code = "var x plus y minus z divby 6 times num2 print "
#lex(code)